package de.bastian.hinterleitner;

import java.util.ArrayList;
import java.util.Calendar;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
import android.text.method.DigitsKeyListener;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import de.bastian.hinterleitner.adaptersviews.StandardAdapter;
import de.bastian.hinterleitner.database.DataHelper;
import de.bastian.hinterleitner.tools.Constants;
import de.bastian.hinterleitner.tools.Entry;
import de.bastian.hinterleitner.tools.EntrySorter;
import de.bastian.hinterleitner.tools.WatchYourCashActivity;
import de.hijacksoft.wyc.R;

/**
 * 
 * @author basti
 */
public class Main extends WatchYourCashActivity implements OnClickListener,
		OnItemClickListener, OnItemLongClickListener {

	private TextView text_monthlytotal, text_eachday, text_budget,
			text_overbudget;
	private Button btn_budget;
	private ProgressBar bar_budget;

	private float budget = 200;

	private ListView list;
	private StandardAdapter listAdapter;

	private static final String TAG = "WatchYourCash_Main";

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		setContentView(R.layout.activity_main);
		initGUI();
		initDB();
	}

	@Override
	protected void onResume() {
		notifyAdapter();
		super.onResume();
	}

	private void notifyAdapter() {
		if (listAdapter != null) {
			listAdapter.entries = EntrySorter.getSingleton(this).sortBy(
					listAdapter.entries, EntrySorter.SORT_BY_DATE);
			listAdapter.notifyDataSetChanged();
		}
	}

	private void initDB() {
		if (!DataHelper.getDataHelper(this).isPreloaded()) {
			startActivityForResult(new Intent(this, LoadingActivity.class),
					Constants.REQUEST_LOAD_DB);
		} else {
			updateData();
			updateTotal();
		}
	}

	private void updateData() {
		listAdapter = new StandardAdapter(this, getThisMonthsItems());
		notifyAdapter();

		list.setAdapter(listAdapter);
	}

	private void initGUI() {
		list = (ListView) findViewById(R.id.main_list);

		LinearLayout layout = new LinearLayout(this);

		LinearLayout parent = new LinearLayout(this);
		LayoutInflater inflator = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		View monthly = inflator.inflate(R.layout.layout_monthly, parent);

		text_budget = (TextView) monthly.findViewById(R.id.main_budget);
		bar_budget = (ProgressBar) monthly.findViewById(R.id.main_progress);
		btn_budget = (Button) monthly.findViewById(R.id.main_button_budget);
		text_monthlytotal = (TextView) monthly
				.findViewById(R.id.main_text_monthlyoverview);
		text_overbudget = (TextView) monthly.findViewById(R.id.main_overbudget);
		text_eachday = (TextView) monthly.findViewById(R.id.main_value_eachday);

		list.addFooterView(layout);

		if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE
				&& getWindowManager().getDefaultDisplay().getWidth() > SCREEN_LIMIT) {
			parent.setLayoutParams(new LinearLayout.LayoutParams(
					LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, 1f));
			((LinearLayout) findViewById(R.id.main_layout_overview))
					.addView(parent);
			list.addHeaderView(new View(this));
		} else {
			list.addHeaderView(parent);
		}

		list.setOnItemClickListener(this);
		list.setOnItemLongClickListener(this);
		btn_budget.setOnClickListener(this);

		initNav(((LinearLayout) findViewById(R.id.main_header)),
				getString(R.string.app_name));
		initFooter(((LinearLayout) findViewById(R.id.main_layout_footer)));
		initLeftNavigation(((LinearLayout) findViewById(R.id.main_layout_overlay)));
	}

	private ArrayList<Entry> getThisMonthsItems() {
		SharedPreferences sp = getSharedPreferences("values", MODE_PRIVATE);
		int day = sp.getInt("starting", 1);
		DataHelper dbHelper = DataHelper.getDataHelper(this);
		ArrayList<Entry> entries = dbHelper.getAllEntriesAt(Calendar
				.getInstance().get(Calendar.YEAR),
				Calendar.getInstance().get(Calendar.MONTH)+1);
		int startMonth = Calendar.getInstance().get(Calendar.MONTH)+1;
		int otherMonth = startMonth;
		if(Calendar.getInstance().get(Calendar.DAY_OF_MONTH)>=day){
			otherMonth++;
		}else{
			startMonth--;
			otherMonth--;
		}
		entries.addAll(dbHelper.getAllEntriesAt(Calendar
				.getInstance().get(Calendar.YEAR),
				otherMonth));
		filter(entries, startMonth);
		return entries;
	}

	private void filter(ArrayList<Entry> entries, int startMonth) {
		SharedPreferences sp = getSharedPreferences("values", MODE_PRIVATE);
		int day = sp.getInt("starting", 1);
		for(int i=0; i<entries.size(); i++){
			Entry e = entries.get(i);
			if(e.getMonth()==startMonth){
				if(e.getDay()<day){
					entries.remove(e);
					i--;
				}
			}else{
				if(e.getDay()>=day){
					entries.remove(e);
					i--;
				}
			}
		}
	}

	private void updateTotal() {
		updateData();
		SharedPreferences sp = getSharedPreferences("values", MODE_PRIVATE);
		boolean show = sp.getBoolean("show_budget", true);
		if(show){
			updateBudget();
		}else{
			updateRevenue();
		}
		
		notifyAdapter();
		notifyWidget();
	}

	private void updateRevenue() {
		double total = 0;
		for (Entry e : listAdapter.getItems()) {
			total += e.getValueAs(getString(R.string.currency), this);
		}
		text_monthlytotal.setText(getString(R.string.totalmonth) + "\n"
				+ roundToDecimals(2, total) + " "
				+ getString(R.string.currency));
		total = 0;
		ArrayList<Entry> all = DataHelper.getDataHelper(this).getAllEntries();
		for (int i=0; i<all.size(); i++) {
			Entry e = all.get(i);
			total += e.getValueAs(getString(R.string.currency), this);
		}
		text_budget.setText(getString(R.string.revenue) + ": "
				+ roundToDecimals(2, total) + getString(R.string.currency));
		bar_budget.setVisibility(View.GONE);
		text_overbudget.setVisibility(View.GONE);
		text_eachday.setVisibility(View.GONE);
		TextView tv = ((TextView) findViewById(R.id.main_text_eachday));
		tv.setVisibility(View.GONE);
	}

	private void updateBudget() {
		SharedPreferences sp = getSharedPreferences("values", MODE_PRIVATE);
		budget = sp.getFloat("budget", 200);
		double total = 0;
		for (Entry e : listAdapter.getItems()) {
			total += e.getValueAs(getString(R.string.currency), this);
		}
		text_monthlytotal.setText(getString(R.string.totalmonth) + "\n"
				+ roundToDecimals(2, total) + " "
				+ getString(R.string.currency));
		text_budget.setText(getString(R.string.budget) + ": "
				+ roundToDecimals(2, budget + total) + "/" + budget + " "
				+ getString(R.string.currency));
		if (total < -budget) {
			bar_budget.setVisibility(View.GONE);
			text_overbudget.setVisibility(View.VISIBLE);
			text_eachday.setVisibility(View.GONE);
			text_overbudget.setText(getString(R.string.overbudget).replace(
					"$1",
					roundToDecimals(2, -budget - total) + " "
							+ getString(R.string.currency)));
			((TextView) findViewById(R.id.main_text_eachday))
					.setVisibility(View.GONE);
		} else {
			bar_budget.setMax((int) budget);
			bar_budget.setProgress((int) (budget + total));
			bar_budget.setVisibility(View.VISIBLE);
			text_overbudget.setVisibility(View.GONE);
			text_eachday.setVisibility(View.VISIBLE);
			text_eachday.setText(getWhatsLeft(-total) + " "
					+ getString(R.string.currency));
			((TextView) findViewById(R.id.main_text_eachday))
					.setVisibility(View.VISIBLE);
		}
	}

	public void onClick(View view) {
		switch (view.getId()) {
		case R.id.main_button_budget:
			changeBudget();
			break;
		}
	}

	private void changeBudget() {
		final SharedPreferences sp = getSharedPreferences("values", MODE_PRIVATE);
		int start = sp.getInt("starting", 1);
		final AlertDialog alertDialog = new AlertDialog.Builder(this).create();
		alertDialog.setTitle(getString(R.string.budget));
		LinearLayout layout = new LinearLayout(this);
		LinearLayout.inflate(this, R.layout.layout_budget, layout);
		final EditText edit = (EditText)layout.findViewById(R.id.budget_edit);
		final Spinner days = (Spinner)layout.findViewById(R.id.budget_spin);
		String[] array = {
				"1.","2.","3.","4.","5.","6.","7.","8.","9.","10.",
				"11.","12.","13.","14.","15.","16.","17.","18.","19.","20.",
				"21.","22.","23.","24.","25.","26.","27.","28.","29.","30.","31."
		};
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, array);
		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		days.setAdapter(adapter);
		days.setSelection(start-1);
		edit.setKeyListener(DigitsKeyListener.getInstance(false, true));
		edit.setText("" + budget);
		final CheckBox cb = (CheckBox)layout.findViewById(R.id.budget_cb);
		cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
			@Override
			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
					edit.setEnabled(isChecked);
			}
		});
		cb.setChecked(!sp.getBoolean("show_budget", true));
		cb.setChecked(sp.getBoolean("show_budget", true));
		alertDialog.setView(layout);
		alertDialog.setButton(getString(R.string.ok),
				new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						SharedPreferences sp = getSharedPreferences("values",
								MODE_PRIVATE);
						try {
							int start = days.getSelectedItemPosition()+1;
							sp.edit().putInt("starting", start).commit();
							sp.edit()
									.putFloat(
											"budget",
											Float.parseFloat(edit.getText()
													.toString())).commit();
						} catch (Exception e) {
							Log.e(TAG, "Error formatting budget!");
						}
						sp.edit().putBoolean("show_budget", cb.isChecked()).commit();
						alertDialog.cancel();
						updateTotal();
					}
				});
		alertDialog.setButton2(getString(R.string.cancel),
				new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						alertDialog.cancel();
					}
				});
		alertDialog.show();
	}

	private void refreshList() {
		listAdapter.setItems(getThisMonthsItems());
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		updateData();
		updateTotal();
	}

	public void onItemClick(AdapterView<?> av, View view, int i, long l) {
		i--; // for the header
		if (i >= listAdapter.getCount())
			return;
		Intent intent = new Intent(this, NewEntry.class);
		intent.putExtra("itemId", "" + listAdapter.getItemId(i));
		startActivityForResult(intent, Constants.REQUEST_EDIT_ITEM);
	}

	public boolean onItemLongClick(AdapterView<?> av, View view, int i, long l) {
		i--; // for the header
		if (i >= listAdapter.getCount())
			return false;
		final int id = i;
		question(
				getString(R.string.deletequestion).replace("$1",
						listAdapter.getItem(id).getName()),
				getString(R.string.yes), getString(R.string.no),
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface di, int i) {
						DataHelper d = DataHelper.getDataHelper(Main.this);
						d.delete((int) listAdapter.getItemId(id));
						refreshList();
						updateTotal();
					}
				}, null);
		return true;
	}

	private double getWhatsLeft(double spent) {
		SharedPreferences sp = getSharedPreferences("values", MODE_PRIVATE);
		int start = sp.getInt("starting", 1);
		double whatsleft = budget - spent;
		int days = start;
		if(Calendar.getInstance().get(Calendar.DAY_OF_MONTH)>=start){
			days += Calendar.getInstance().getActualMaximum(
					Calendar.DAY_OF_MONTH)
					- Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
		}else{
			days -= Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
		}
		return roundToDecimals(2, whatsleft / days);
	}

	@Override
	public boolean hasOptionsMenu() {
		return false;
	}
}
